package com.openmanus.agent.memory;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * 记忆项
 * 表示智能体记忆系统中的一个记忆条目
 * 
 * @author OpenManus Team
 * @version 1.0.0
 */
@Getter
@Setter
@Builder
public class MemoryItem {

    /**
     * 记忆键（唯一标识）
     */
    private String key;

    /**
     * 记忆内容
     */
    private String content;

    /**
     * 记忆类型
     */
    private MemoryType type;

    /**
     * 重要性评分（0.0-1.0）
     */
    @Builder.Default
    private double importance = 0.5;

    /**
     * 访问次数
     */
    @Builder.Default
    private int accessCount = 0;

    /**
     * 创建时间
     */
    @Builder.Default
    private LocalDateTime createdAt = LocalDateTime.now();

    /**
     * 最后访问时间
     */
    private LocalDateTime lastAccessedAt;

    /**
     * 最后更新时间
     */
    private LocalDateTime lastUpdatedAt;

    /**
     * 过期时间
     */
    private LocalDateTime expiresAt;

    /**
     * 元数据
     */
    private Map<String, Object> metadata;

    /**
     * 向量嵌入（用于相似性搜索）
     */
    private float[] embedding;

    /**
     * 记忆类型枚举
     */
    public enum MemoryType {
        /**
         * 对话记忆
         */
        CONVERSATION("对话记忆"),

        /**
         * 任务记忆
         */
        TASK("任务记忆"),

        /**
         * 知识记忆
         */
        KNOWLEDGE("知识记忆"),

        /**
         * 经验记忆
         */
        EXPERIENCE("经验记忆"),

        /**
         * 上下文记忆
         */
        CONTEXT("上下文记忆"),

        /**
         * 临时记忆
         */
        TEMPORARY("临时记忆");

        private final String description;

        MemoryType(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 增加访问次数并更新最后访问时间
     */
    public void incrementAccess() {
        this.accessCount++;
        this.lastAccessedAt = LocalDateTime.now();
    }

    /**
     * 更新内容并设置更新时间
     * 
     * @param newContent 新内容
     */
    public void updateContent(String newContent) {
        this.content = newContent;
        this.lastUpdatedAt = LocalDateTime.now();
    }

    /**
     * 检查记忆是否已过期
     * 
     * @return 是否过期
     */
    public boolean isExpired() {
        return expiresAt != null && LocalDateTime.now().isAfter(expiresAt);
    }

    /**
     * 检查记忆是否为高重要性
     * 
     * @return 是否为高重要性
     */
    public boolean isHighImportance() {
        return importance >= 0.8;
    }

    /**
     * 检查记忆是否为低重要性
     * 
     * @return 是否为低重要性
     */
    public boolean isLowImportance() {
        return importance <= 0.2;
    }

    /**
     * 获取记忆年龄（天数）
     * 
     * @return 记忆年龄
     */
    public long getAgeInDays() {
        return java.time.Duration.between(createdAt, LocalDateTime.now()).toDays();
    }

    /**
     * 获取元数据值
     * 
     * @param key 键名
     * @return 元数据值
     */
    @SuppressWarnings("unchecked")
    public <T> T getMetadata(String key) {
        if (metadata == null) {
            return null;
        }
        return (T) metadata.get(key);
    }

    /**
     * 设置元数据值
     * 
     * @param key 键名
     * @param value 值
     */
    public void setMetadata(String key, Object value) {
        if (metadata == null) {
            metadata = new java.util.HashMap<>();
        }
        metadata.put(key, value);
    }

    /**
     * 检查是否包含指定元数据
     * 
     * @param key 键名
     * @return 是否包含
     */
    public boolean hasMetadata(String key) {
        return metadata != null && metadata.containsKey(key);
    }

    /**
     * 生成记忆摘要
     * 
     * @return 记忆摘要
     */
    public String generateSummary() {
        StringBuilder summary = new StringBuilder();
        summary.append("记忆键: ").append(key).append("\n");
        summary.append("类型: ").append(type.getDescription()).append("\n");
        summary.append("重要性: ").append(String.format("%.2f", importance)).append("\n");
        summary.append("访问次数: ").append(accessCount).append("\n");
        summary.append("创建时间: ").append(createdAt).append("\n");
        summary.append("内容: ").append(content.length() > 100 ? 
            content.substring(0, 100) + "..." : content).append("\n");
        
        if (isExpired()) {
            summary.append("状态: 已过期\n");
        }
        
        return summary.toString();
    }

    @Override
    public String toString() {
        return generateSummary();
    }
}
